import 'package:flutter/material.dart';

///[context] 上下文 [close()]关闭当前sheet
typedef Widget Builder(BuildContext context, void close());

class CustomeBottomSheet {
  OverlayEntry overlayEntry;
  BuildContext context;

  ///[context] 构建上下文 [child]构建子对象
  CustomeBottomSheet(context, Builder builder, vsync,
      {double viewPortHeightRate = 0.5, Duration duration}) {
    this.context = context;

    this.overlayEntry = new OverlayEntry(builder: (context) {
      return new Positioned(
          top: 0,
          right: 0,
          left: 0,
          bottom: 0,
          child: new SafeArea(
              child: new Material(
                  color: Colors.transparent,
                  child: SheetPanel(
                    builder: builder,
                    viewPortRate: viewPortHeightRate,
                    onClose: () {
                      this.close();
                    },
                  ))));
    });
  }

  ///显示对话框
  show() {
    if (overlayEntry != null) {
      Overlay.of(context).insert(overlayEntry);
    }
  }

  ///关闭对话框
  close() {
    if (overlayEntry != null) {
      overlayEntry.remove();
    }
  }
}

typedef void Complated();

class SheetPanel extends StatefulWidget {
  //final Widget child;
  final Builder builder;
  final bool isShow;
  final double viewPortRate;
  final Complated onClose;

  const SheetPanel({
    Key key,
    this.builder,
    this.isShow = true,
    this.viewPortRate = 0.5,
    this.onClose,
  }) : super(key: key);

  @override
  _SheetPanelState createState() => _SheetPanelState();
}

class _SheetPanelState extends State<SheetPanel> with TickerProviderStateMixin {
  AnimationController animationController;
  Animation<Offset> animation;
  Animation<double> opacityValue;
  bool isClose;
  double height;
  @override
  void initState() {
    animationController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 250))
          ..addListener(() {
            // print(animationController.value);
            if (animationController.value == 0 && isClose) {
              this.widget.onClose();
            }
            setState(() {});
          });
    animation = Tween<Offset>(
            begin: Offset(0, 1), end: Offset(0, 1 - this.widget.viewPortRate))
        .animate(
            CurvedAnimation(parent: animationController, curve: Curves.linearToEaseOut));

    opacityValue = Tween<double>(begin: 0, end: (1 - this.widget.viewPortRate))
        .animate(animationController);
    animationController.forward();
    super.initState();
  }

  @override
  void dispose() {
    animationController.dispose();
    super.dispose();
  }

  close() {
    isClose = true;
    animationController.reverse(from: 1);
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Container(
          color: Colors.black.withOpacity(opacityValue.value),
          child: GestureDetector(
            onTap: () {
              close();
            },
          ),
        ),
        //使用平移，不要使用Positioned,会出现移除情况
        SlideTransition(
          position: animation,
          child: this.widget.builder(context, close),
        ),
      ],
    );
  }
}
